<?php

namespace MicroCyanHelper\Plan\WechatRev\Traits;

trait Config
{

    private $cache_access_token = 'ff_access_token';
    private $cache_sync_key = 'ff_sync_key__';


    /**
     * @description 获取access_token
     * @param bool $refresh
     * @return string
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    private function get_access_token(bool $refresh=false): string
    {
        //强制刷新access_token
        if ($refresh) $this->cache->delete($this->cache_access_token);
        //从缓存中读取access_token
        $token = $this->cache->get($this->cache_access_token);
        if (is_string($token)&&strlen($token)>10) return $token;
        //请求新的access_token
        $options = [];
        $options['query'] = [];
        $options['query']['userName']   = $this->config['username']??'';
        $options['query']['passWord']   = $this->config['password']??'';
        $o = $this->http->get('/Login',$options)->getBody()->getContents();
        $o = json_decode($o??'{}',true);
        if (!empty($o['obj'])){
            $token = 'Bearer '.$o['obj'];
            $this->cache->set($this->cache_access_token,$token,3600*2);
            return $token;
        }
        throw new \Exception('获取access_token失败');
    }

    /**
     * @description 执行post请求
     * @param string $path
     * @param array $config 机器人的相关信息，token和代理
     * @param array $options
     * @return array|mixed
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    private function http_post(string $path,array $config,array $options = []){
        //格式化body为数组
        if (!empty($options['body'])){
            if (!is_array($options['body'])){
                $options['body'] = json_decode($options['body'],true);
            }
        }else{
            $options['body'] = [];
        }
        //配置代理信息
        if (!empty($config['proxy'])){
            $options['body']['proxy'] = [];
            if (is_string($config['proxy'])&&preg_match_all("/[\.\w]+/",$config['proxy'],$matches)>=4){
                $options['body']['proxy'] = [];
                $options['body']['proxy']['proxyIp'] = $matches[0][0];
                $options['body']['proxy']['proxyPort'] = $matches[0][1];
                $options['body']['proxy']['proxyUser'] = $matches[0][2];
                $options['body']['proxy']['proxyPass'] = $matches[0][3];
                $options['body']['proxy']['proxyType'] = 0;
            }else if (!empty($config['proxy']['proxyIp'])&&!empty($config['proxy']['proxyPort'])&&!empty($config['proxy']['proxyUser'])&&!empty($config['proxy']['proxyPass'])){
                $options['body']['proxy'] = [];
                $options['body']['proxy']['proxyIp'] = $config['proxy']['proxyIp'];
                $options['body']['proxy']['proxyPort'] = $config['proxy']['proxyPort'];
                $options['body']['proxy']['proxyUser'] = $config['proxy']['proxyUser'];
                $options['body']['proxy']['proxyPass'] = $config['proxy']['proxyPass'];
                $options['body']['proxy']['proxyType'] = 0;
            }else{
                unset($options['body']['proxy']);
            }
        }
        //配置机器人信息
        if (!empty($config['token'])){
            if (is_string($config['token'])){
                $config['token'] = json_decode($config['token'],true);
            }
            if (!empty($config['token']['uin'])&&!empty($config['token']['sessionKey'])&&!empty($config['token']['deviceId'])){
                $options['body']['user'] = $config['token'];
                if (!empty($syncKey = $this->cache->get($this->cache_sync_key.$config['token']['uin']))&&strlen($syncKey)>10){
                    $options['body']['user']['syncKey'] = $syncKey;
                }
            }
        }
        $options['body'] = json_encode($options['body'],JSON_UNESCAPED_SLASHES);
        if (empty($options['headers'])||!is_array($options['headers'])) $options['headers'] = [];
        $options['headers']['Authorization'] = $this->get_access_token();
        try {
            $o = $this->http->request('POST',$path,$options)->getBody()->getContents();
            if (preg_match("/session.*error/i",$o)){
                throw new \Exception('抱歉，机器人登录信息已过期',88080);
            }
            return json_decode($o,true)??[];
        }catch (\Exception $exception){
            if (preg_match("/401.*Unauthorized/i",$exception->getMessage())){
                $this->cache->delete($this->cache_access_token);
                throw new \Exception('抱歉，逆向登录信息已过期',88081);
            }else if (preg_match("/500.*Internal.*Server.*Error/i",$exception->getMessage())){
                throw new \Exception('抱歉，IP不可用',88082);
            }
            throw $exception;
        }
    }

}